﻿/*
                                                                                                                             
@@@        @@@@@@   @@@@@@@   @@@@@@@      @@@  @@@   @@@@@@   @@@  @@@     @@@@@@@   @@@@@@@    @@@@@@    @@@@@@    @@@@@@@@
@@@       @@@@@@@@  @@@@@@@@  @@@@@@@@     @@@  @@@  @@@@@@@@  @@@@ @@@     @@@@@@@@  @@@@@@@@  @@@@@@@@  @@@@@@@@  @@@@@@@@@
@@!       @@!  @@@  @@!  @@@  @@!  @@@     @@!  @@@  @@!  @@@  @@!@!@@@     @@!  @@@  @@!  @@@  @@!  @@@  @@!  @@@  !@@      
!@!       !@!  @!@  !@!  @!@  !@!  @!@     !@!  @!@  !@!  @!@  !@!!@!@!     !@!  @!@  !@!  @!@  !@!  @!@  !@!  @!@  !@!      
@!!       @!@  !@!  @!@!!@!   @!@  !@!     @!@  !@!  @!@!@!@!  @!@ !!@!     @!@@!@!   @!@!!@!   @!@!@!@!  @!@!@!@!  !@! @!@!@
!!!       !@!  !!!  !!@!@!    !@!  !!!     !@!  !!!  !!!@!!!!  !@!  !!!     !!@!!!    !!@!@!    !!!@!!!!  !!!@!!!!  !!! !!@!!
!!:       !!:  !!!  !!: :!!   !!:  !!!     :!:  !!:  !!:  !!!  !!:  !!!     !!:       !!: :!!   !!:  !!!  !!:  !!!  :!!   !!:
 :!:      :!:  !:!  :!:  !:!  :!:  !:!      ::!!:!   :!:  !:!  :!:  !:!     :!:       :!:  !:!  :!:  !:!  :!:  !:!  :!:   !::
 :: ::::  ::::: ::  ::   :::   :::: ::       ::::    ::   :::   ::   ::      ::       ::   :::  ::   :::  ::   :::   ::: ::::
: :: : :   : :  :    :   : :  :: :  :         :       :   : :  ::    :       :         :   : :   :   : :   :   : :   :: :: :
					  _    _    _     _    _    _    _    _    _    _    _    _    _    _    _    _    _  
					 / \  / \  / \   / \  / \  / \  / \  / \  / \  / \  / \  / \  / \  / \  / \  / \  / \ 
					( T )( h )( e ) ( H )( i )( e )( r )( a )( r )( c )( h )( i )( t )( e )( c )( t )( s )
					 \_/  \_/  \_/   \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/ 
					 
					 
Chapter 2: Office Politics
Mastering and practising business etiquette gives you an edge when you are being considered for employment or advancement.

The Interview
Give a firm handshake when arriving and leaving; stand up to greet the interviewer.

Executive Etiquette
Don't expect people to follow rules if you do not follow them yourself.

The Internet & E-Mail
Use the "blind carbon copy" (Bcc) field when sending group e-mails. This way you won’t divulge the names of the other people you are writing to.

How Men Should Deal with Women at the Office
Remember, the only thing women want is to be treated with respect and equality. Forget sexual distinctions - treat women as people.

Romance at the office
Keep your affair under wraps until you have committed to a long-term relationship.

Asking for a Raise
Ask for a raise after a major coup or at your yearly review. Use your business acumen to sell yourself. 
*/

package org.tbyrne.motion{
	import fl.transitions.*;
	
	import org.tbyrne.utils.DelayedCall;
	import org.tbyrne.utils.MemoryTools;
	
	public class MultiTween extends Tween{
		public function get delay():Number{
			return _delay;
		}
		public function get subject():Object{
			return obj;
		}
		
		public function get timeUntilFinish(): Number
		{
			var t: Number = 0;
			if (this.initCall != null && this.initCall.pending)
			{
				t += this.initCall.remainingDelay;
			}
			t += (this.duration - this.position);
			return t;
		}
		
		protected var _target:Object;
		protected var _tween:Tween
		protected var _properties:Array;
		protected var _startValues:Array;
		protected var _endValues:Array;
		protected var _useSeconds:Boolean;
		protected var _duration:Number;
		protected var _easing:Function;
		protected var _delay:Number;
		protected var initCall:DelayedCall;
		private var ignoreSuper:Boolean = true;
		
		public function MultiTween(target:Object, properties:Array, easing:Function, startValues:Array, endValues:Array, duration:Number, useSeconds:Boolean, delay:Number=0){
			super(target, properties[0], easing, confirmStartValues(startValues,target,properties), endValues[0], duration, useSeconds);
			if(!target){
				throw new Error("MultiTween(): target must be non-null.");
			}
			// clears any other tweens that are be affecting the same properties
			var tweens:Array = MemoryTools.getLockedInstances(MultiTween);
			for(var i:int=0; i<tweens.length; i++){
				var tween:MultiTween = tweens[i];
				if(tween.subject==target){
					for(var j:int=0; j<properties.length; j++){
						tween.stopProperty(properties[j]);
					}
				}
			}
			
			MemoryTools.lock(this);
			ignoreSuper = false;
			_target = target;
			_properties = properties;
			//if(startValues)_startValues = startValues;
			_endValues = endValues;
			_useSeconds = useSeconds;
			_duration = duration;
			_easing = easing;
			_delay = delay;
			if(delay){
				initCall = new DelayedCall(init,[],useSeconds?delay*1000:delay,useSeconds);
			}else{
				init();
			}
		}
		protected function confirmStartValues(startValues:Array, target:Object, properties:Array):Number{
			if(startValues){
				_startValues = startValues;
			}else{
				_startValues = [];
				for(var i:int=0; i<properties.length; i++){
					_startValues[i] = target[properties[i]]
				}
			}
			return _startValues[0];
		}
		public function get properties(): Array
		{
			return this._properties.slice();
		}
		protected function init():void{
			initCall = null;
			_tween = new Tween(this, "position", _easing, 0, 1, _duration, _useSeconds);
			_tween.addEventListener(TweenEvent.MOTION_FINISH,dispatchFinish);
			_tween.addEventListener(TweenEvent.MOTION_CHANGE,dispatchChange);
			_tween.addEventListener(TweenEvent.MOTION_LOOP,dispatchLoop);
			_tween.addEventListener(TweenEvent.MOTION_RESUME,dispatchResume);
			_tween.addEventListener(TweenEvent.MOTION_START,dispatchStart);
			_tween.addEventListener(TweenEvent.MOTION_STOP,dispatchStop);
			setPosition(0);
		}
		protected function dispatchFinish(e:TweenEvent):void{
			this.dispatchEvent(new MultiTweenEvent(MultiTweenEvent.MOTION_FINISH, _tween.time, getPositions()));
			MemoryTools.unlock(this);
		}
		protected function dispatchChange(e:TweenEvent):void{
			this.dispatchEvent(new MultiTweenEvent(MultiTweenEvent.MOTION_CHANGE, _tween.time, getPositions()));
		}
		protected function dispatchLoop(e:TweenEvent):void{
			this.dispatchEvent(new MultiTweenEvent(MultiTweenEvent.MOTION_LOOP, _tween.time, getPositions()));
		}
		protected function dispatchResume(e:TweenEvent):void{
			this.dispatchEvent(new MultiTweenEvent(MultiTweenEvent.MOTION_RESUME, _tween.time, getPositions()));
		}
		protected function dispatchStart(e:TweenEvent):void{
			this.dispatchEvent(new MultiTweenEvent(MultiTweenEvent.MOTION_START, _tween.time, getPositions()));
		}
		protected function dispatchStop(e:TweenEvent):void{
			this.dispatchEvent(new MultiTweenEvent(MultiTweenEvent.MOTION_STOP, _tween.time, getPositions()));
			MemoryTools.unlock(this);
		}
	    public function getPositions(t:Number=NaN):Array{
	        if (isNaN(t)) t = _tween.time;
	        var ret:Array = [];
			for(var i:int=0; i<_properties.length; i++){
				var prop:String = _properties[i];
				var subj:Object = (_target is Array?_target[0]:_target);
				ret[i] = subj[prop];
			}
	        return ret;
	    }
	    public function stopProperty(property:String):void{
	    	var index:Number = _properties.indexOf(property);
	    	if(index!=-1){
	    		_properties.splice(index);
	    		_startValues.splice(index);
	    		_endValues.splice(index);
	    		if(!_properties.length){
	    			stop();
	    		}
	    	}
	    }
		override public function setPosition(p:Number):void{
			if(!ignoreSuper){
				for(var i:int=0; i<_properties.length; i++){
					var prop:String = _properties[i];
					var start:Number = _startValues[i];
					var end:Number = _endValues[i];
					var value:Number = start+(Number(end)-Number(start))*p;
					_setProp(_target,prop,value);
				}
			}
		}
		protected function _setProp(target:Object, prop:String, value:Number):void{
			if(target is Array){
				var array:Array = (target as Array);
				for(var i:int=0; i<array.length; i++){
					array[i][prop] = value;
				}
			}else{
				target[prop] = value;
			}
		}
		
		// proxy methods
		override public function start():void{
			if(!ignoreSuper){
				if(!_tween)init();
				_tween.start();
			}
		}
		override public function stop():void{
			if(_tween)_tween.stop();
			if(initCall){
				initCall.clear();
				initCall = null;
			}
		}
		override public function resume():void{
			_tween.resume();
		}
		override public function rewind(t:Number=0):void{
			_tween.rewind(t);
		}  
		override public function fforward():void{
			_tween.fforward();
		}   
		override public function nextFrame():void{
			_tween.nextFrame();
		}
		override public function prevFrame():void{
			_tween.prevFrame();
		}
		override public function continueTo(finish:Number, duration:Number):void {
			_tween.continueTo(finish, duration);
		}
		override public function yoyo():void {
			_tween.yoyo();
		}
	}
}